﻿/**
 * 
 */
package com.zc.springproject.dao;

import java.sql.*;
import java.util.ArrayList;

import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.stereotype.Repository;

//import com.alibaba.druid.pool.DruidDataSource;

/**
 * @author ZhangCheng 2019年9月16日
 * @coding UTF-8
 */
@Repository("basicDAO")
public abstract class BasicDAO<T> {

	private Connection con;
	private PreparedStatement ps;
	private ResultSet re;
	private String driverName = "com.mysql.jdbc.Driver";
	private String url;
	private String user;
	private String pwd;
	
//	public Connection getCon() {
//		return this.con;
//	}
	/**
	 * 将结果集转换成ArrayList集合
	 */
	public abstract ArrayList<T> resultSetToArrayList(ResultSet re);

	/**
	 * 静态代码块加载数据库驱动 在创建对象前就建立好连接
	 */

	static {
		try {
			Class.forName("com.mysql.jdbc.Driver");
			System.out.println("加载数据库驱动成功！");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

////	/**
////	 * 构造方法 加载数据库驱动 并设置默认数据库连接
////	 */
	/**
	 * 构造方法 加载数据库驱动 并设置默认数据库连接 数据连接池的应用
	 */
	public BasicDAO() {
		this("jdbc:mysql://localhost:3306/zcdatabasespring?useSSL=false", "root", "zhangcheng");

	}
//	/**
//	 * 构造方法 加载数据库驱动 并设置默认数据库连接  数据连接池的应用 DBCP
//	 */
//
//	public BasicDAO(String url, String user, String pwd) {
//	
//		@SuppressWarnings("resource")
//		BasicDataSource poolSource = new BasicDataSource();
//		poolSource.setDriverClassName(this.driverName);
//		poolSource.setUrl(url);
//		poolSource.setUsername(user);
//		poolSource.setPassword(pwd);
//		
//		try {
//			this.con = poolSource.getConnection();
//		} catch (SQLException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//	}
	/**
	 * 构造方法 加载数据库驱动 并设置默认数据库连接  数据连接池的应用 Ali Druid
	 */

//	public BasicDAO(String url, String user, String pwd) {
//	
//		@SuppressWarnings("resource")
//		DruidDataSource poolSource = new DruidDataSource();
//		poolSource.setDriverClassName(this.driverName);
//		poolSource.setUrl(url);
//		poolSource.setUsername(user);
//		poolSource.setPassword(pwd);
//		
//		try {
//			this.con = poolSource.getConnection();
//		} catch (SQLException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//	}

	/**
	 * 构造方法 加载数据库驱动 并设置默认数据库连接
	 */

	public BasicDAO(String url, String user, String pwd) {
		this.url = url;
		this.user = user;
		this.pwd = pwd;
	}

//	public ArrayList<Object> resultSetToArratList(ResultSet re){
//		ArrayList<Object> obj = new ArrayList<Object>();
//		try {
//			int columnCount = re.getMetaData().getColumnCount();
//			while(re.next()) {
//				obj.add(e)
//			}
//		} catch (SQLException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//	}

	/**
	 * 与数据库进行连接
	 */
	public void getCon() {
		try {
			this.con = DriverManager.getConnection(url, user, pwd);
//			System.out.println("数据库连接成功！");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 用预编译查询获取信息
	 * 
	 * @throws SQLException
	 */
	public ArrayList<T> getInfoFromDB(String sql) {
		return getInfoFromDB(sql, new Object[0]);
	}

	/**
	 * 通过数组传递参数
	 * 
	 * @throws SQLException
	 */
	public ArrayList<T> getInfoFromDBByArray(String sql, Object[] obj) {
		return getInfoFromDB(sql, obj);
	}

	/**
	 * 通过可变参数传递参数
	 * 
	 * @throws SQLException
	 */
	public ArrayList<T> getInfoFromDB(String sql, Object... obj) {
		getCon();// 获得数据库连接
		try {
			this.ps = this.con.prepareStatement(sql);// 获得预编译对象

			if (obj.length > 0) {
				for (int i = 0; i < obj.length; i++) {
					this.ps.setObject(i + 1, obj[i]);
				}
			}
			System.out.println(this.ps.toString());
			this.re = this.ps.executeQuery();// 进行预编译查询
		} catch (SQLException e) {

			e.printStackTrace();
		}

		return resultSetToArrayList(this.re);
	}

	/**
	 * 无参 进行DML查询
	 * 
	 * @throws SQLException
	 */
	public int updateDML(String sql) throws SQLException {
		return updateDML(sql, new Object[0]);
	}

	/**
	 * 通过数组传递参数 并进行DML操作
	 * 
	 * @throws SQLException
	 */
	public int updateDMLByArray(String sql, Object[] obj) throws SQLException {
		return updateDML(sql, obj);
	}

	/**
	 * 通过可变参数传递参数 并进行DML操作
	 * 
	 * @throws SQLException
	 */
	public int updateDML(String sql, Object... obj) throws SQLException {
		getCon();// 获得数据库连接
		this.ps = this.con.prepareStatement(sql);// 获得预编译对象
		if (obj.length > 0) {
			for (int i = 0; i < obj.length; i++) {
				this.ps.setObject(i + 1, obj[i]);
			}
		}
		System.out.println(this.ps.toString());
		int count = this.ps.executeUpdate();// 进行预编译查询
//		closeAll();
		System.out.println("影响了" + count + "条数据");
		return count;
	}

	/**
	 * 关闭所有连接
	 * 
	 * @throws SQLException
	 */
	public void closeAll() {
		try {
			if (this.re != null) {
				this.re.close();
			}
			if (this.ps != null) {
				this.ps.close();
			}
			if (this.con != null) {
				this.con.close();
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
